{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2.1.0\n",
      "sys.version_info(major=3, minor=6, micro=9, releaselevel='final', serial=0)\n",
      "matplotlib 3.1.3\n",
      "numpy 1.18.1\n",
      "pandas 1.0.1\n",
      "sklearn 0.22.1\n",
      "tensorflow 2.1.0\n",
      "tensorflow_core.python.keras.api._v2.keras 2.2.4-tf\n"
     ]
    }
   ],
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "import tensorflow as tf\n",
    "\n",
    "from tensorflow import keras\n",
    "\n",
    "print(tf.__version__)\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, tf, keras:\n",
    "    print(module.__name__, module.__version__)\n",
    "\n",
    "'''\n",
    "使用for循环 ，并使用 model.add()的方式，循环添加深层次的模型\n",
    "数据批归一化\n",
    "'''"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(5000, 28, 28) (5000,)\n",
      "(55000, 28, 28) (55000,)\n",
      "(10000, 28, 28) (10000,)\n"
     ]
    }
   ],
   "source": [
    "fashion_mnist = keras.datasets.fashion_mnist\n",
    "(x_train_all, y_train_all), (x_test, y_test) = fashion_mnist.load_data()\n",
    "x_valid, x_train = x_train_all[:5000], x_train_all[5000:]\n",
    "y_valid, y_train = y_train_all[:5000], y_train_all[5000:]\n",
    "\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "print(x_train.shape, y_train.shape)\n",
    "print(x_test.shape, y_test.shape)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# x = (x - u) / std\n",
    "\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler()\n",
    "# x_train: [None, 28, 28] -> [None, 1]\n",
    "x_train_scaled = scaler.fit_transform(\n",
    "    x_train.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)\n",
    "x_valid_scaled = scaler.transform(\n",
    "    x_valid.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)\n",
    "x_test_scaled = scaler.transform(\n",
    "    x_test.astype(np.float32).reshape(-1, 1)).reshape(-1, 28, 28)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# tf.keras.models.Sequential()\n",
    "\n",
    "## 通过循环 向 模型中添加层次，形成深层次的model\n",
    "## 设置批归一化，在每一层之间设置归一化层次。keras把归一化操作也封装成一个layer\n",
    "\n",
    "model = keras.models.Sequential()\n",
    "model.add(keras.layers.Flatten(input_shape=[28, 28]))\n",
    "for _ in range(20):\n",
    "    model.add(keras.layers.Dense(100, activation=\"relu\"))\n",
    "    model.add(keras.layers.BatchNormalization())\n",
    "    \"\"\"\n",
    "    model.add(keras.layers.Dense(100))\n",
    "    model.add(keras.layers.BatchNormalization())\n",
    "    model.add(keras.layers.Activation('relu'))\n",
    "    \"\"\"\n",
    "model.add(keras.layers.Dense(10, activation=\"softmax\"))\n",
    "\n",
    "model.compile(loss=\"sparse_categorical_crossentropy\",\n",
    "              optimizer = \"sgd\",\n",
    "              metrics = [\"accuracy\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "flatten_1 (Flatten)          (None, 784)               0         \n",
      "_________________________________________________________________\n",
      "dense_21 (Dense)             (None, 100)               78500     \n",
      "_________________________________________________________________\n",
      "batch_normalization_20 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_22 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_21 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_23 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_22 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_24 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_23 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_25 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_24 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_26 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_25 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_27 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_26 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_28 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_27 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_29 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_28 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_30 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_29 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_31 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_30 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_32 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_31 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_33 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_32 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_34 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_33 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_35 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_34 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_36 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_35 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_37 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_36 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_38 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_37 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_39 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_38 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_40 (Dense)             (None, 100)               10100     \n",
      "_________________________________________________________________\n",
      "batch_normalization_39 (Batc (None, 100)               400       \n",
      "_________________________________________________________________\n",
      "dense_41 (Dense)             (None, 10)                1010      \n",
      "=================================================================\n",
      "Total params: 279,410\n",
      "Trainable params: 275,410\n",
      "Non-trainable params: 4,000\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Train on 55000 samples, validate on 5000 samples\n",
      "Epoch 1/10\n",
      "55000/55000 [==============================] - 31s 570us/sample - loss: 1.8318 - accuracy: 0.3967 - val_loss: 0.9749 - val_accuracy: 0.6646\n",
      "Epoch 2/10\n",
      "55000/55000 [==============================] - 23s 416us/sample - loss: 1.0681 - accuracy: 0.6244 - val_loss: 0.7640 - val_accuracy: 0.7196\n",
      "Epoch 3/10\n",
      "55000/55000 [==============================] - 23s 423us/sample - loss: 0.9317 - accuracy: 0.6681 - val_loss: 0.6615 - val_accuracy: 0.7612\n",
      "Epoch 4/10\n",
      "55000/55000 [==============================] - 23s 423us/sample - loss: 0.8535 - accuracy: 0.6979 - val_loss: 0.6149 - val_accuracy: 0.7712\n",
      "Epoch 5/10\n",
      "55000/55000 [==============================] - 23s 418us/sample - loss: 0.8022 - accuracy: 0.7167 - val_loss: 0.5723 - val_accuracy: 0.7904\n",
      "Epoch 6/10\n",
      "55000/55000 [==============================] - 23s 416us/sample - loss: 0.7615 - accuracy: 0.7321 - val_loss: 0.5510 - val_accuracy: 0.7976\n",
      "Epoch 7/10\n",
      "55000/55000 [==============================] - 23s 417us/sample - loss: 0.7372 - accuracy: 0.7417 - val_loss: 0.5272 - val_accuracy: 0.8116\n",
      "Epoch 8/10\n",
      "55000/55000 [==============================] - 24s 427us/sample - loss: 0.7028 - accuracy: 0.7536 - val_loss: 0.5045 - val_accuracy: 0.8202\n",
      "Epoch 9/10\n",
      "55000/55000 [==============================] - 23s 422us/sample - loss: 0.6817 - accuracy: 0.7639 - val_loss: 0.4961 - val_accuracy: 0.8194\n",
      "Epoch 10/10\n",
      "55000/55000 [==============================] - 23s 426us/sample - loss: 0.6638 - accuracy: 0.7681 - val_loss: 0.4808 - val_accuracy: 0.8324\n"
     ]
    }
   ],
   "source": [
    "# Tensorboard, earlystopping, ModelCheckpoint\n",
    "logdir = './dnn-bn-callbacks'\n",
    "if not os.path.exists(logdir):\n",
    "    os.mkdir(logdir)\n",
    "output_model_file = os.path.join(logdir,\n",
    "                                 \"fashion_mnist_model.h5\")\n",
    "\n",
    "callbacks = [\n",
    "    keras.callbacks.TensorBoard(logdir),\n",
    "    keras.callbacks.ModelCheckpoint(output_model_file,\n",
    "                                    save_best_only = True),\n",
    "    keras.callbacks.EarlyStopping(patience=5, min_delta=1e-3),\n",
    "]\n",
    "history = model.fit(x_train_scaled, y_train, epochs=10,\n",
    "                    validation_data=(x_valid_scaled, y_valid),\n",
    "                    callbacks = callbacks)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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3H777cyfP7/Dz6qtrWX+/PnNtjvnnHMAWLx4MT/72c8wxjBlyhT+8Ic/8OGHH/L5z3+eXbt2AXD//fczZMgQLr744sSTxn72s59RW1vLbbfdxty5c5k2bRqrVq3iqquu4sQTT+T2228nGAxSWlrKH//4RwYOHEhtbS1f+cpXWL16NcYYvve971FdXc3bb7/NPffcA8BvfvMbNm/ezN13331Mf9+WFM4iInLMuvN9zj6fj2XLljXbbu3atWzatInbb7+dV199lf79+1NRUQHADTfcwFlnncWyZcuIRCLU1tZSWVl51M8IBoOsXr0agMrKSl5//XWMMTz00EP89Kc/5a677uKHP/whhYWFiUeSVlZW4na7+b//+z/uvPNO3G43v//97/n1r399rH++VhTOIiJZJrmH2/KZ1MdL8vucDx06lHif80033cTKlStxOByJ9zkPGjToqPuy1nLrrbc22+7gwYO8/PLLLFy4kP79+wNQUlICwMsvv8zixYsBcDqdFBYWdhjOixYtSkzv27ePRYsWceDAAYLBIKNHjwbgpZdeYsmSJYlyxcXFAJxzzjk8++yznHTSSYRCISZPntzJv1bHFM4iItItFi5cyOOPP84HH3zAokWL+OMf/8ihQ4dYs2YNbrebUaNG4ff7O9xPV7dL5nK5iEajifmW2ze+UxrgK1/5Cl/72te49NJLWbFiBbfddttR933ddddxxx13MGHCBK699tpO1StVuiBMRES6xaJFi1iyZAmPP/44CxcupLq6mgEDBuB2u1m+fDl79uxJaT/tbXfOOefwl7/8hfLy2BuJGw9rz5s3L/F6yEgkQnV1NQMHDuTgwYOUl5cTCAR49tlnj/p5Q4cOBeCRRx5JLD/33HO57777EvONvfHZs2ezd+9e/vSnP3HVVVel+ufpFIWziIh0i7be57x69WomT57M4sWLU36fc3vbTZw4kW9/+9ucddZZTJ06la997WsA3HvvvSxfvpzJkyczY8YMNm/ejNvt5rvf/S6zZs3i3HPPPepn33bbbSxcuJAZM2YkDpkDfOc736GyspJJkyYxdepUli9fnlj3iU98gjPOOCNxqLu76bC2iIh0m+54n3Nb29XU1ABw9dVXc/XVVzdbN3DgQJ5++ulW+7nhhhu44YYbWi1fsWJFs/n58+e3eRV5fn5+s550slWrVnHTTTe124Zj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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "def plot_learning_curves(history):\n",
    "    pd.DataFrame(history.history).plot(figsize=(8, 5))\n",
    "    plt.grid(True)\n",
    "    plt.gca().set_ylim(0, 3)\n",
    "    plt.show()\n",
    "\n",
    "plot_learning_curves(history)\n",
    "\n",
    "# 1. 参数众多，训练不充分\n",
    "# 2. 梯度消失 -> 链式法则 -> 复合函数f(g(x))\n",
    "#    批归一化缓解梯度消失"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "10000/10000 [==============================] - 2s 166us/sample - loss: 0.5074 - accuracy: 0.8160\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "[0.5073772555828094, 0.816]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "model.evaluate(x_test_scaled, y_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
